local BuffManager = class("BuffManager")
local FightConst = require("const.FightConst")

local OVERLAY_BUFF = {
    ["BuffConfusion"] = 1,
    ["BuffShareHurt"] = 1,
    ["BuffResistHurt"] = 1,
    ["BuffRidicule"] = 1
}

local CONFUSION_BUFF = {
    ["BuffConfusion"] = 1
}

function BuffManager:ctor()
    self._buffList = {}
    self._removeList = {}
    self._sheildId = 0
end

function BuffManager:getSheildId()
    self._sheildId = self._sheildId + 1
    return self._sheildId
end

function BuffManager:removeBuffByEntity(entity)
    for i = 1, #self._buffList do
        if self._buffList[i]:getEntity():getId() == entity:getId() then
            self._buffList[i]:remove()
        end
    end
    self:_clearBuff()
end

function BuffManager:addBuff(buff, battleReport)
    if not self:PreProcessBuff(buff, battleReport) then
        return
    end
    buff:addManager(self)
    self:addBuffReport(buff, battleReport)
    buff:checkExcute(FightConst.BUFF_EFF_IMMEDIATELY, battleReport)
    table.insert(self._buffList, buff)
end

function BuffManager:checkResistBuff(entity) -- 检查有是否抵挡buff
    for i = 1, #self._buffList do
        local buff = self._buffList[i]
        if buff:getBuffClass() == "BuffResistHurt" and buff:checkCondEntity(entity) then
            return buff:getEntity()
        end
    end
end

function BuffManager:checkRidiculeBuff(entity)
    for i = 1, #self._buffList do
        local buff = self._buffList[i]
        if buff:getBuffClass() == "BuffRidicule" and buff:checkCondEntity(entity) then
            return buff:getWhoEntity()
        end
    end
end

function BuffManager:PreProcessBuff(buff, battleReport) -- 预处理要添加的buff
    if buff:getEntity():isDie() then
        return false
    end
    local buffClass = buff:getBuffClass()
    if CONFUSION_BUFF[buffClass] then -- 混乱型buff
        local AttributeConst = require("const.AttributeConst")
        local entity = buff:getEntity()
        local confusionAttr = entity:getAttrValue(AttributeConst.CONFUSION_RESIST) -- 混乱抵抗
        local radomNum = math.random(1, 1000)
        if radomNum <= confusionAttr then
            return false
        end
    end
    if OVERLAY_BUFF[buffClass] then -- 对于覆盖型buff，添加新buff时旧的删除
        for i = 1, #self._buffList do
            if
                self._buffList[i]:getEntity():getId() == buff:getEntity():getId() and
                    self._buffList[i]:getBuffClass() == buffClass
             then
                self._buffList[i]:remove(battleReport)
            end
        end
    end
    return true
end

function BuffManager:checkBuffExcuteByEffectTime(effeType, entity, battleReport, ...)
    for i = 1, #self._buffList do
        local buff = self._buffList[i]
        if buff:checkCondEntity(entity) then
            buff:checkExcute(effeType, battleReport, ...)
        end
    end
end

function BuffManager:roundBeforeBuff(battleReport)
    for i = 1, #self._buffList do
        local buff = self._buffList[i]
        if buff:getCheckType() == FightConst.BUFF_ROUND then
            buff:checkOn(battleReport)
        end
    end
    self:_clearBuff(battleReport)
end

function BuffManager:actionBeforeBuff(battleReport, entity)
    self:_buffCheckOn(FightConst.BUFF_ACTION_BEGIN, battleReport, entity)
end

function BuffManager:actionAfterBuff(battleReport, entity)
    self:_buffCheckOn(FightConst.BUFF_ACTION_END, battleReport, entity)
end

function BuffManager:_buffCheckOn(type, battleReport, entity)
    for i = 1, #self._buffList do
        local buff = self._buffList[i]
        if buff:getCheckType() == type and buff:getEntity():getId() == entity:getId() then
            buff:checkOn(battleReport)
        end
    end
    self:_clearBuff(battleReport)
end

function BuffManager:removeBuff(buff, battleReport)
    table.insert(self._removeList, buff)
    if battleReport then
        self:removeBuffReport(buff, battleReport)
    end
end

function BuffManager:addBuffReport(buff, battleReport)
    local param = {}
    param.type = FightConst.BUFF_ADD
    param.id = buff:getId()
    printDebug("添加buff " .. buff:getId())
    battleReport:addBuff(param, buff:getEntity())
end

function BuffManager:afectBuffReport(buff, dtValue, battleReport)
    local param = {}
    local config = buff:getConfig()
    param.type = FightConst.BUFF_AFFECT
    param.attrId = config.attack_attr
    param.id = buff:getId()
    param.value = dtValue
    param.toneup = config.toneup
    local AttributeConst = require("const.AttributeConst")
    printDebug("作用buff " .. buff:getId())
    param.element = config.toneup == 0 and AttributeConst.ELEMENT_PHYSICS or AttributeConst.ELEMENT_TREATMENT
    battleReport:addBuff(param, buff:getEntity())
end

function BuffManager:removeBuffReport(buff, battleReport)
    local param = {}
    local config = buff:getConfig()
    param.type = FightConst.BUFF_REMOVE
    param.id = buff:getId()
    param.attrId = config.attack_attr
    printDebug("删除buff " .. buff:getId())
    param.value = buff:getEntity():getAttrValue(config.attack_attr)
    battleReport:addBuff(param, buff:getEntity())
end

function BuffManager:_clearBuff()
    local removeBuf = function(buff)
        for i = 1, #self._buffList do
            if buff == self._buffList[i] then
                table.remove(self._buffList, i)
                break
            end
        end
    end
    for i = 1, #self._removeList do
        removeBuf(self._removeList[i])
    end
    self._removeList = {}
end

function BuffManager:destroy()
end

return BuffManager
